package com.atguigu.springcloud.AOP;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.UnexpectedRollbackException;

/**
 * 日志切面示例
 *
 * @author XiongJianLin
 * @date Created in 2025/2/28 10:27
 */

@Aspect
@Component
public class LoggingAspect {
    // 定义切点：拦截 UserService 中的所有方法
    @Pointcut("execution(* com.atguigu.springcloud.AOP.service.AopUserService.*(..))")
    public void userServiceMethods() {
    }

    // 定义切点：拦截所有被 @Loggable 注解标记的方法
    @Pointcut("@annotation(Loggable)")
    public void loggableMethods() {
    }

    // 前置通知：在目标方法执行前记录日志，并输出方法参数
    @Before("userServiceMethods()")
    public void beforeAdvice(JoinPoint joinPoint) {
        System.out.println("[日志] 准备执行方法: " + joinPoint.getSignature().getName());
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            System.out.println("[日志] 方法参数: " + arg);
        }
    }

    // 后置通知：在目标方法执行后记录日志
    @After("userServiceMethods()")
    public void afterAdvice(JoinPoint joinPoint) {
        System.out.println("[日志] 方法执行完成: " + joinPoint.getSignature().getName());
    }

//    // 前置通知：在目标方法执行前记录日志，并输出方法参数
//    @Before("loggableMethods()")
//    public void beforeAnnotationAdvice(JoinPoint joinPoint) {
//        System.out.println("[日志] 准备执行方法: " + joinPoint.getSignature().getName());
//        Object[] args = joinPoint.getArgs();
//        for (Object arg : args) {
//            System.out.println("[日志] 方法参数: " + arg);
//        }
//    }
//
//    // 后置通知：在目标方法执行后记录日志
//    @After("loggableMethods()")
//    public void afterAnnotationAdvice(JoinPoint joinPoint) {
//        System.out.println("[日志] 方法执行完成: " + joinPoint.getSignature().getName());
//    }


    /**
     * 环绕通知：在目标方法执行前后添加额外逻辑
     * </br> 异常处理
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around("loggableMethods()")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        try {
            System.out.println("[环绕通知] 方法执行前: " + joinPoint.getSignature().getName());

            // 执行目标方法
            Object result = joinPoint.proceed();

            System.out.println("[环绕通知] 方法执行后: " + joinPoint.getSignature().getName());
            return result;

        } catch (UnexpectedRollbackException e) {
            //  处理问题：手动回滚，则捕获回滚异常，历史中手动回滚
            e.printStackTrace();
//            PlatformTransactionManager transactionManager = transactionTemplate.getTransactionManager();
//            transactionManager.rollback(transactionManager.getTransaction(transactionTemplate));
//            return res[0];
        }
    }


}
